package com.zjj.spring.read.xml.event;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

/**
 * 在一个线程中发布事件，另一个线程中监听事件并执行，实现了代码解耦，
 * 并且由于异步操作，发布事件线程不会被监听事件阻塞，提高吞吐
 * <pre>
 * ApplicationEvent：表示事件本身，自定义事件需要继承该类,可以用来传递数据,比如上述操作,我们需要将用户的邮箱地址传给事件监听器.
 * ApplicationEventPublisherAware：事件发送器,通过实现这个接口,来触发事件.
 * ApplicationListener：事件监听器接口,事件的业务逻辑封装在监听器里面.
 * </pre>
 * <pre>
 * ContextRefreshedEvent:	ApplicationContext被初始化或刷新时，该事件被发布，
 * 							这也可以在ConfigurableApplicationContext接口中使用refresh()方法来发生。
 * ContextStartedEvent: 	当使用ConfigurableApplicationContext接口中的start()方法启动ApplicationContext时，
 * 							该事件被发布，你可以调查你的数据库，或者你可以在接受到这个事件后重启任何停止的应用程序。
 * ContextStoppedEvent:	当使用ConfigurableApplicationContext接口中的stop()方法停止ApplicationContext时，
 * 						发布这个事件，你可以在接受到这个事件后做必要的清理工作。
 * ContextCloseEvent:	当使用ConfigurableApplicationContext接口中的close()方法关闭ApplicationContext时，
 * 						该事件被发布，一个已关闭的上下文到达生命周期末端，它不能被刷新或重启。
 * RequestHandledEvent:	这是一个web-specific事件，告诉所有beanHTTP请求已经被服务（特殊请求）。
 * </pre>
 * 可以自定义Publisher如下EmailPublisher，也可以直接使用ApplicationContext发布
 * @author zhuangjiajie778
 */
public class EmailPublisher implements ApplicationEventPublisherAware{

    private ApplicationEventPublisher _applicationEventPublisher;

	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
		this._applicationEventPublisher = applicationEventPublisher;
	}

    public void  publishEvent(ApplicationEvent applicationEvent) {
    	System.out.println("EmailPublisher start puslish event : " + applicationEvent.getSource().toString());
        this._applicationEventPublisher.publishEvent(applicationEvent);
    }

}
